package com.abing.starry.config.intercepter;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.abing.starry.common.ErrorCode;
import com.abing.starry.exception.BusinessException;
import com.abing.starry.exception.ThrowUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;

import static com.abing.starry.constant.UserConstant.USER_LOGIN_STATE;

/**
 * @Author CaptainBing
 * @Date 2024/8/16 18:37
 * @Description 续期拦截器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RenewalInterceptor implements HandlerInterceptor {


    private final StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader("X-Token");
        ThrowUtils.throwIf(StringUtils.isEmpty(token), ErrorCode.NOT_LOGIN_ERROR);

        JWT jwt = JWTUtil.parseToken(token);
        String id = String.valueOf(jwt.getPayload("id"));

        String cacheToken = stringRedisTemplate.opsForValue().get(USER_LOGIN_STATE + id);
        ThrowUtils.throwIf(StringUtils.isEmpty(cacheToken),ErrorCode.NOT_LOGIN_ERROR);

        if (!StringUtils.equals(token,cacheToken)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }

        Long timestamp = jwt.getPayloads().getLong(JWTPayload.EXPIRES_AT);
        long currentTimeMillis = System.currentTimeMillis();
        if (timestamp > currentTimeMillis){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR,"token 已过期");
        }

        long offsetTimeStamp = currentTimeMillis - timestamp;
        long halfHour = 1000 * 60 * 30 * 1000;
        // 过期时间小于半小时续期
        if (offsetTimeStamp < halfHour){
            stringRedisTemplate.expire(USER_LOGIN_STATE + id, Duration.ofHours(2));
        }
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}
